import api, { getResponseCount } from '@/store/api';
import i18n from '@/i18n';
const { t } = i18n.global as any;

const getHealthStatus = (events: any, loadedEvents: any) => {
  let status = loadedEvents ? 'OK' : '';
  for (const event of events) {
    if (event.severity === 'Warning') {
      status = 'Warning';
    }
    if (event.severity === 'Critical') {
      status = 'Critical';
      break;
    }
  }
  return status;
};

// TODO: High priority events should also check if Log
// is resolved when the property is available in Redfish
const getHighPriorityEvents = (events: any[]) =>
  events.filter(({ severity }) => severity === 'Critical');

export interface Log {
  id: string;
  severity: string;
  date: Date;
  type: string;
  description: string;
  name: string;
  modifiedDate: Date;
  uri: string;
  filterByStatus: string;
  status: boolean;
  additionalDataUri: string;
}

export const useEventLogStore = defineStore('EventLog', () => {
  const allEvents = ref([] as Log[]);
  const loadedEvents = ref(false);

  const highPriorityEvents = computed(() =>
    getHighPriorityEvents(allEvents.value),
  );
  const healthStatus = computed(() =>
    getHealthStatus(allEvents.value, loadedEvents.value),
  );

  const setAllEvents = (Events: any) => (
    (allEvents.value = Events), (loadedEvents.value = true)
  );

  const getEventLogData = async () => {
    const eventLogs = await cutEventLogs(
      '/redfish/v1/Systems/system/LogServices/EventLog/Entries',
    );
    setAllEvents(eventLogs);
  };
  const cutEventLogs = async (url: string) => {
    return await api
      .get(url)
      .then(async ({ data }) => {
        let eventLogs = data.Members.map(
          (log: {
            [x: string]: any;
            Id?: any;
            Severity?: any;
            Created?: any;
            EntryType?: any;
            Message?: any;
            Name?: any;
            Modified?: any;
            Resolved?: any;
            AdditionalDataURI?: any;
          }) => {
            const {
              Id,
              Severity,
              Created,
              EntryType,
              Message,
              Name,
              Modified,
              Resolved,
              AdditionalDataURI,
            } = log;
            return {
              id: Id,
              severity: Severity,
              date: new Date(Created),
              type: EntryType,
              description: Message,
              name: Name,
              modifiedDate: new Date(Modified),
              uri: log['@odata.id'],
              filterByStatus: Resolved ? 'Resolved' : 'Unresolved',
              status: Resolved, //true or false
              additionalDataUri: AdditionalDataURI,
            };
          },
        );
        if (data['Members@odata.nextLink']) {
          eventLogs = [
            ...eventLogs,
            ...(await cutEventLogs(data['Members@odata.nextLink'])),
          ];
        }
        return eventLogs;
      })
      .catch((error) => {
        console.log('Event Log Data:', error);
      });
  };
  const deleteAllEventLogs = async (data: string | any[]) => {
    return await api
      .post(
        '/redfish/v1/Systems/system/LogServices/EventLog/Actions/LogService.ClearLog',
        '',
        undefined,
      )
      .then(() => getEventLogData())
      .then(() => t('pageEventLogs.toast.successDelete', data.length))
      .catch((error) => {
        console.log(error);
        throw new Error(t('pageEventLogs.toast.errorDelete', data.length));
      });
  };
  const deleteEventLogs = async (uris = [] as string[]) => {
    const promises = uris.map((uri) =>
      api.delete(uri, undefined).catch((error) => {
        console.log(error);
        return error;
      }),
    );
    return await api
      .all(promises)
      .then((response) => {
        getEventLogData();
        return response;
      })
      .then(
        api.spread((...responses) => {
          const { successCount, errorCount } = getResponseCount(responses);
          const toastMessages = [];

          if (successCount) {
            const message = t(
              'pageEventLogs.toast.successDelete',
              successCount,
            );
            toastMessages.push({ type: 'success', message });
          }

          if (errorCount) {
            const message = t('pageEventLogs.toast.errorDelete', errorCount);
            toastMessages.push({ type: 'error', message });
          }

          return toastMessages;
        }),
      );
  };
  const resolveEventLogs = async (logs: any[]) => {
    const promises = logs.map((log: { uri: string }) =>
      api.patch(log.uri, { Resolved: true }).catch((error) => {
        console.log(error);
        return error;
      }),
    );
    return await api
      .all(promises)
      .then((response) => {
        getEventLogData();
        return response;
      })
      .then(
        api.spread((...responses) => {
          const { successCount, errorCount } = getResponseCount(responses);
          const toastMessages = [];
          if (successCount) {
            const message = t(
              'pageEventLogs.toast.successResolveLogs',
              successCount,
            );
            toastMessages.push({ type: 'success', message });
          }
          if (errorCount) {
            const message = t(
              'pageEventLogs.toast.errorResolveLogs',
              errorCount,
            );
            toastMessages.push({ type: 'error', message });
          }
          return toastMessages;
        }),
      );
  };
  const unresolveEventLogs = async (logs: any[]) => {
    const promises = logs.map((log: { uri: string }) =>
      api.patch(log.uri, { Resolved: false }).catch((error) => {
        console.log(error);
        return error;
      }),
    );
    return await api
      .all(promises)
      .then((response) => {
        getEventLogData();
        return response;
      })
      .then(
        api.spread((...responses) => {
          const { successCount, errorCount } = getResponseCount(responses);
          const toastMessages = [];
          if (successCount) {
            const message = t(
              'pageEventLogs.toast.successUnresolveLogs',
              successCount,
            );
            toastMessages.push({ type: 'success', message });
          }
          if (errorCount) {
            const message = t(
              'pageEventLogs.toast.errorUnresolveLogs',
              errorCount,
            );
            toastMessages.push({ type: 'error', message });
          }
          return toastMessages;
        }),
      );
  };
  // Single log entry
  const updateEventLogStatus = async (log: { status: any; uri: string }) => {
    const updatedEventLogStatus = log.status;
    return await api
      .patch(log.uri, { Resolved: updatedEventLogStatus })
      .then(() => {
        getEventLogData();
      })
      .then(() => {
        if (log.status) {
          return t('pageEventLogs.toast.successResolveLogs', 1);
        } else {
          return t('pageEventLogs.toast.successUnresolveLogs', 1);
        }
      })
      .catch((error) => {
        console.log(error);
        throw new Error(
          t('pageEventLogs.toast.errorLogStatusUpdate') as string,
        );
      });
  };

  return {
    allEvents,
    loadedEvents,
    highPriorityEvents,
    healthStatus,
    setAllEvents,
    getEventLogData,
    cutEventLogs,
    deleteAllEventLogs,
    deleteEventLogs,
    resolveEventLogs,
    unresolveEventLogs,
    updateEventLogStatus,
  };
});
